package com.yanqu.road.server.logic.task;

import com.yanqu.road.entity.autodata.task.UserObjectTaskData;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.event.EventTriggerArgs;
import com.yanqu.road.entity.event.IObjectEventListener;
import com.yanqu.road.entity.task.TaskConditionInfo;
import com.yanqu.road.entity.task.TaskInfo;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.gameplayer.module.task.TaskModule;
import com.yanqu.road.server.manger.config.TaskMgr;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public abstract class BaseObjectCondition {

    private static final Logger logger = LogManager.getLogger(BaseObjectCondition.class.getName());

    protected GamePlayer player;
    private Map<Integer, UserObjectTaskData> taskDataMap = new ConcurrentHashMap<>();
    private List<Integer> taskIds = new ArrayList<>();
    /**
     * 任务条件
     */
    protected int completeType;

    public BaseObjectCondition() {
    }

    public void init(int completeType, GamePlayer player, List<Integer> taskIds, Map<Integer, UserObjectTaskData> taskDataMap) {
        this.completeType = completeType;
        this.taskIds = taskIds;
        this.player = player;
        if (taskDataMap != null) {
            this.taskDataMap = new ConcurrentHashMap<>(taskDataMap);
        }
    }


    public void addTrigger(GamePlayer player) {
        player.getModule(TaskModule.class).getGameObjectEvent().addListener(completeType, handle);
    }

    ;

    public void removeTrigger(GamePlayer player) {
        player.getModule(TaskModule.class).getGameObjectEvent().removeListener(completeType, handle);
    }

    /**
     * 是否已经完成了
     *
     * @param objectId
     * @param taskId
     * @return
     */
    public boolean isAlreadyFinished(int objectId, Integer taskId) {
        UserObjectTaskData userObjectTaskData = taskDataMap.get(objectId);
        if (userObjectTaskData != null && userObjectTaskData.isFinish(taskId)) {
            return true;
        }

        return false;
    }

    public Property finish(int objectId, Integer taskId) {
        if (canComplete(objectId, taskId) != 0) {
            return null;
        }

        TaskInfo taskInfo = getTaskInfo(taskId);
        if (taskInfo == null) {
            return null;
        }

        UserObjectTaskData userObjectTaskData = getTaskDataNewIfNull(objectId);
        userObjectTaskData.addFinishTaskId(taskId);
        player.getModule(TaskModule.class).objectTaskChange(userObjectTaskData);
        // 添加奖励
        player.getModule(CurrencyModule.class).addCurrency(taskInfo.getReward(), eLogMoneyType.Task, eLogMoneyType.TaskGetReward);

        return taskInfo.getReward();
    }

    private UserObjectTaskData getTaskDataNewIfNull(int objectId) {
        if (!taskDataMap.containsKey(objectId)) {
            UserObjectTaskData userObjectTaskData = player.getModule(TaskModule.class).getObjectTaskDataNewIfNull(objectId, completeType);
            taskDataMap.put(objectId, userObjectTaskData);
        }
        return taskDataMap.get(objectId);
    }

    protected abstract int canComplete(int objectId, Integer taskId);

    public final BigInteger getValue(int objectId) {
        if (!taskDataMap.containsKey(objectId)) {
            return BigInteger.ZERO;
        }
        return taskDataMap.get(objectId).getValue();
    }

    public final void setValue(int objectId, BigInteger value) {
        UserObjectTaskData taskData = getTaskDataNewIfNull(objectId);
        taskData.setValue(value);
        taskData.setLastUpdateTime(DateHelper.getCurrentTime());
        player.getModule(TaskModule.class).objectTaskChange(taskData);
    }


    public static BaseObjectCondition createCondition(GamePlayer player, int completeType, List<Integer> taskIds, Map<Integer, UserObjectTaskData> taskDataMap) {
        try {
            return ObjectTaskConditionFactory.createCondition(player, completeType, taskIds, taskDataMap);
        } catch (Exception e) {
            logger.error("创建任务条件{}失败,err:{}", completeType, e);
        }
        return null;
    }


    public long getUserId() {
        return player.getUserId();
    }

    public List<TaskConditionInfo> getTaskInfoList() {
        List<TaskConditionInfo> taskInfoList = new ArrayList<>();
        for (Integer taskId : taskIds) {
            TaskConditionInfo taskConditionById = TaskMgr.getTaskConditionById(taskId);
            if (taskConditionById == null) {
                continue;
            }
            taskInfoList.add(taskConditionById);
        }
        return taskInfoList;
    }

    public TaskConditionInfo getTaskConditionInfo(Integer taskId) {
        if (!taskIds.contains(taskId)) {
            return null;
        }
        TaskConditionInfo taskConditionById = TaskMgr.getTaskConditionById(taskId);
        return taskConditionById;
    }

    public TaskInfo getTaskInfo(Integer taskId) {
        if (!taskIds.contains(taskId)) {
            return null;
        }
        return TaskMgr.getTaskInfoById(taskId);
    }


    protected abstract void changeValue(int objectId, Object object);

    protected final eventListenHandle handle = new eventListenHandle();

    public class eventListenHandle implements IObjectEventListener {
        @Override
        public void triggerEvent(int objectId, EventTriggerArgs eventArgs) {
            changeValue(objectId, eventArgs.getArgs());
        }

        @Override
        public int checkCanComplete(int objectId, int taskId) {
            return canComplete(objectId, taskId);
        }

        @Override
        public Property objectTaskFinish(int objectId, Integer taskId) {
            return finish(objectId, taskId);
        }
    }
}
